#pragma once
#include <jsoncpp/json/json.h>
#include "Socket.hpp"
using namespace SocketModule;

class Request
{
public:
    Request() {}
    Request(int x, int y, char oper)
    {
        serialize(x, y, oper);
    }
    Request(const std::string &json_str)
    {
        if (!deserialize(json_str))
            LOG(LogLevel::ERROR) << "Response: 反序列化失败! ";
    }
    // 序列化
    std::string serialize(int x, int y, char oper)
    {
        Json::Value root;
        root["x"] = _x = x;
        root["y"] = _y = y;
        root["oper"] = _oper = oper;
        Json::FastWriter writer;
        _json_str = writer.write(root);
        return _json_str;
    }
    // 反序列化
    bool deserialize(const std::string &json_ptr)
    {
        Json::Value root;
        Json::Reader reader;
        if (reader.parse(json_ptr, root))
        {
            _json_str = json_ptr;
            _x = root["x"].asInt();
            _y = root["y"].asInt();
            _oper = root["oper"].asInt();
            return true;
        }
        return false;
    }
    int X() const { return _x; }
    int Y() const { return _y; }
    int Oper() const { return _oper; }
    std::string JsonStr() const { return _json_str; }

private:
    int _x, _y;
    char _oper;
    std::string _json_str;
};

class Response
{
public:
    Response() {}
    Response(int result, int status)
    {
        serialize(result, status);
    }
    Response(const std::string &json_str)
    {
        if (!deserialize(json_str))
            LOG(LogLevel::ERROR) << "Response: 反序列化失败! ";
    }
    // 序列化
    std::string serialize(int result, int status)
    {
        Json::Value root;
        root["result"] = _result = result;
        root["status"] = _status = status;
        Json::FastWriter writer;
        _json_str = writer.write(root);
        return _json_str;
    }
    // 反序列化
    bool deserialize(const std::string &json_str)
    {
        Json::Value root;
        Json::Reader reader;
        if (reader.parse(json_str, root))
        {
            _json_str = json_str;
            _result = root["result"].asInt();
            _status = root["status"].asInt();
            return true;
        }
        return false;
    }
    int Result() const { return _result; }
    int Status() const { return _status; }
    std::string JsonStr() const { return _json_str; }

private:
    int _result, _status;
    std::string _json_str;
};

using request_handler = std::function<Response(const Request &)>;
class Protocol
{
public:
    Protocol(request_handler handler)
        : _handler(handler)
    {
    }
    // 封装
    // package = size + esp + json_ptr + esp
    void encapsulate(const std::string &json_str, std::string &package)
    {
        int size = json_str.size();
        package = std::to_string(size) + esp + json_str + esp;
    }
    // 解封装
    bool decapsulate(std::string &package, std::string &json_str)
    {
        auto pos = package.find(esp);
        if (pos == std::string::npos)
        {
            return false;
        }

        std::string size_str = package.substr(0, pos);
        int size = std::stoi(size_str.c_str());
        int total_len = size_str.size() + 2 * esp.size() + size;
        if (package.size() >= total_len)
        {
            json_str = package.substr(pos + esp.size(), size);
            package.erase(0, total_len);
            return true;
        }
        return false;
    }

    void ClientService()
    {
        // todo
    }

    // 服务器端服务
    std::string ServerService(std::string &package)
    {
        std::string buffer, json_str, send_msg;
        if (decapsulate(package, json_str))
        {
            Request request(json_str);
            // 使用顶层提供的回调函数来处理请求
            Response response = _handler(request);
            encapsulate(response.JsonStr(), send_msg);
        }
        return send_msg;
    }

private:
    static const std::string esp;
    // 顶层提供的用于处理请求的回调方法
    request_handler _handler;
};
const std::string Protocol::esp = "/n/r";